package com.lbiuse.wx.api;

import java.util.List;

import com.lbiuse.wx.bean.Status;
import com.lbiuse.wx.bean.media.MediaId;
import com.lbiuse.wx.bean.message.MessageType;
import com.lbiuse.wx.bean.message.mass.Article;
import com.lbiuse.wx.bean.message.mass.MassStatus;
import com.lbiuse.wx.bean.message.mass.MsgId;
import com.lbiuse.wx.bean.message.send.CustomMessage;
import com.lbiuse.wx.util.WxHttpUtils;
import net.sf.json.JSONObject;

import org.apache.log4j.Logger;



/**
 * 消息API
 * 
 */
public class MessageAPI {

	private static Logger logger = Logger.getLogger(MessageAPI.class);

	private static final String SEND_CUSTOM_MESSAGE_URL = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN";
	private static final String SEND_MASS_MESSAGE_ALL = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token=ACCESS_TOKEN";
	private static final String SEND_MASS_MESSAGE = "https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token=ACCESS_TOKEN";
	private static final String UPLOAD_VIDEO = "https://file.api.weixin.qq.com/cgi-bin/media/uploadvideo?access_token=ACCESS_TOKEN";
	private static final String UPLOAD_NEWS = "https://api.weixin.qq.com/cgi-bin/media/uploadnews?access_token=ACCESS_TOKEN";
	private static final String MASS_MESSAGE_PREVIEW = "https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token=ACCESS_TOKEN";
	private static final String MASS_MESSAGE_QUERY_STATUS = "https://api.weixin.qq.com/cgi-bin/message/mass/get?access_token=ACCESS_TOKEN";
	private static final String MASS_MESSAGE_DELETE = "https://api.weixin.qq.com/cgi-bin/message/mass/delete?access_token=ACCESS_TOKEN";

	/**
	 * 发送客服消息
	 * 
	 * @param appId
	 *            -第三方用户唯一凭证
	 * @param message
	 *            -JSON形式的客服消息
	 * @return
	 */
	public static Status sendCustomMessage(String appId, String message) {
		String token = BaseAPI.getAccessToken(appId);
		if (token == null) {
			logger.error("发送客服消息失败，获取AccessToken失败!");
			return new Status(-4, "获取AccessToken失败");
		}
		String url = SEND_CUSTOM_MESSAGE_URL.replace("ACCESS_TOKEN", token);
		logger.debug(message);
		return WxHttpUtils.post(url, message, Status.class);
	}

	/**
	 * 发送客服消息
	 * 
	 * @param appId
	 *            -第三方用户唯一凭证
	 * @param message
	 *            -客服消息
	 * @param openId
	 *            -普通用户openid
	 * @return
	 */
	public static Status sendCustomMessage(String appId, CustomMessage message,
			String openId) {
		String token = BaseAPI.getAccessToken(appId);
		if (token == null) {
			logger.error("发送客服消息失败，获取AccessToken失败!");
			return new Status(-4, "获取AccessToken失败");
		}
		String url = SEND_CUSTOM_MESSAGE_URL.replace("ACCESS_TOKEN", token);
		String json = message.toJSON(openId);
		logger.debug(json);
		return WxHttpUtils.post(url, json, Status.class);
	}

	/**
	 * 高级群发消息
	 * 
	 * @param appId
	 *            -第三方用户唯一凭证
	 * @param type
	 *            -消息类型
	 * @param mediaId
	 *            -文本类型为文本内容，其它类型为消息Id
	 * @return
	 */
	public static MsgId sendMassMessage(String appId, MessageType type,
			String mediaId) {
		if (type.equals(MessageType.video)) {
			type = MessageType.mpvideo;
		}
		String temp = "media_id";
		if (type.equals(MessageType.text)) {
			temp = "content";
		}
		JSONObject json = new JSONObject();
		JSONObject filter = new JSONObject();
		filter.put("is_to_all", true);
		json.put("filter", filter);
		json.put("msgtype", type.toString());
		JSONObject content = new JSONObject();
		content.put(temp, mediaId);
		json.put(type.toString(), content);
		String msg = json.toString();
		String token = BaseAPI.getAccessToken(appId);
		if (token == null) {
			logger.error("高级群发消息失败，获取AccessToken失败!");
			return new MsgId(-4, "获取AccessToken失败");
		}
		String url = SEND_MASS_MESSAGE.replace("ACCESS_TOKEN", token);
		logger.debug(json);
		return WxHttpUtils.post(url, msg, MsgId.class);
	}

	/**
	 * 按openId列表进行高级群发
	 * 
	 * @param appId
	 *            -第三方用户唯一凭证
	 * @param type
	 *            -消息类型
	 * @param mediaId
	 *            -文本类型为文本内容，其它类型为消息Id
	 * @param openIds
	 *            -消息的接收者，一串OpenID列表，OpenID最少1个，最多10000个
	 * @return
	 */
	public static MsgId sendMassMessage(String appId, MessageType type,
			String mediaId, List<String> openIds) {
		if (type.equals(MessageType.mpvideo)) {
			type = MessageType.video;
		}
		String temp = "media_id";
		if (type.equals(MessageType.text)) {
			temp = "content";
		}
		JSONObject json = new JSONObject();
		json.put("touser", openIds);
		json.put("msgtype", type.toString());
		JSONObject content = new JSONObject();
		content.put(temp, mediaId);
		json.put(type.toString(), content);
		String msg = json.toString();
		String token = BaseAPI.getAccessToken(appId);
		if (token == null) {
			logger.error("按openId列表进行高级群发失败，获取AccessToken失败!");
			return new MsgId(-4, "获取AccessToken失败");
		}
		String url = SEND_MASS_MESSAGE.replace("ACCESS_TOKEN", token);
		logger.debug(json);
		return WxHttpUtils.post(url, msg, MsgId.class);
	}

	/**
	 * 根据分组过滤进行高级群发
	 * 
	 * @param appId
	 *            -第三方用户唯一凭证
	 * @param type
	 *            -消息类型
	 * @param mediaId
	 *            -文本类型为文本内容，其它类型为消息Id
	 * @param groupId
	 *            -群发到的分组的group_id
	 * @return
	 */
	public static MsgId sendMassMessage(String appId, MessageType type,
			String mediaId, String groupId) {
		if (type.equals(MessageType.video)) {
			type = MessageType.mpvideo;
		}
		String temp = "media_id";
		if (type.equals(MessageType.text)) {
			temp = "content";
		}
		JSONObject json = new JSONObject();
		JSONObject filter = new JSONObject();
		filter.put("is_to_all", false);
		filter.put("group_id", groupId);
		json.put("filter", filter);
		json.put("msgtype", type.toString());
		JSONObject content = new JSONObject();
		content.put(temp, mediaId);
		json.put(type.toString(), content);
		String msg = json.toString();
		String token = BaseAPI.getAccessToken(appId);
		if (token == null) {
			logger.error("根据分组过滤进行高级群发失败，获取AccessToken失败!");
			return new MsgId(-4, "获取AccessToken失败");
		}
		String url = SEND_MASS_MESSAGE_ALL.replace("ACCESS_TOKEN", token);
		logger.debug(json);
		return WxHttpUtils.post(url, msg, MsgId.class);
	}

	/**
	 * 上传图文消息素材
	 * 
	 * @param appId
	 *            -第三方用户唯一凭证
	 * @param articles
	 *            -图文消息，一个图文消息支持1到10条图文
	 * @return
	 */
	public static MediaId uploadNews(String appId, List<Article> articles) {
		JSONObject json = new JSONObject();
		json.put("articles", articles);
		String msg = json.toString();
		String token = BaseAPI.getAccessToken(appId);
		if (token == null) {
			logger.error("上传图文消息素材失败，获取AccessToken失败!");
			return new MediaId(-4, "获取AccessToken失败");
		}
		String url = UPLOAD_NEWS.replace("ACCESS_TOKEN", token);
		logger.debug(json);
		return WxHttpUtils.post(url, msg, MediaId.class);
	}

	/**
	 * 上传视频
	 * 
	 * @param appId
	 *            -第三方用户唯一凭证
	 * @param mediaId
	 *            -通过基础支持中的上传下载多媒体文件来得到
	 * @param title
	 *            -消息的标题
	 * @param description
	 *            -消息的描述
	 * @return
	 */
	public static MediaId uploadVideo(String appId, String mediaId,
			String title, String description) {
		JSONObject json = new JSONObject();
		json.put("media_id", mediaId);
		json.put("title", title);
		json.put("description", description);
		String msg = json.toString();
		String token = BaseAPI.getAccessToken(appId);
		if (token == null) {
			logger.error("上传视频失败，获取AccessToken失败!");
			return new MediaId(-4, "获取AccessToken失败");
		}
		String url = UPLOAD_VIDEO.replace("ACCESS_TOKEN", token);
		logger.debug(json);
		return WxHttpUtils.post(url, msg, MediaId.class);
	}

	/**
	 * 预览接口
	 * 
	 * @param appId
	 *            -第三方用户唯一凭证
	 * @param type
	 *            -消息类型
	 * @param mediaId
	 *            -文本类型为文本内容，其它类型为消息Id
	 * @param openId
	 *            -接收消息用户对应该公众号的openid
	 */
	public static MsgId preview(String appId, MessageType type, String mediaId,
			String openId) {
		if (type.equals(MessageType.video)) {
			type = MessageType.mpvideo;
		}
		String temp = "media_id";
		if (type.equals(MessageType.text)) {
			temp = "content";
		}
		JSONObject json = new JSONObject();
		json.put("touser", openId);
		json.put("msgtype", type.toString());
		JSONObject content = new JSONObject();
		content.put(temp, mediaId);
		json.put(type.toString(), content);
		String msg = json.toString();
		String token = BaseAPI.getAccessToken(appId);
		if (token == null) {
			logger.error("获取AccessToken失败!");
			return new MsgId(-1, "获取AccessToken失败");
		}
		String url = MASS_MESSAGE_PREVIEW.replace("ACCESS_TOKEN", token);
		logger.debug(json);
		return WxHttpUtils.post(url, msg, MsgId.class);
	}

	/**
	 * 删除群发
	 * 
	 * @param appId
	 *            -第三方用户唯一凭证
	 * @param msgId
	 *            -发送出去的消息ID
	 * @return
	 */
	public static Status delete(String appId, String msgId) {
		JSONObject json = new JSONObject();
		json.put("msg_id", msgId);
		String msg = json.toString();
		String token = BaseAPI.getAccessToken(appId);
		if (token == null) {
			logger.error("删除群发失败，获取AccessToken失败!");
			return new MediaId(-4, "获取AccessToken失败");
		}
		String url = MASS_MESSAGE_DELETE.replace("ACCESS_TOKEN", token);
		logger.debug(json);
		return WxHttpUtils.post(url, msg, Status.class);
	}

	/**
	 * 查询群发消息发送状态
	 * 
	 * @param appId
	 *            -第三方用户唯一凭证
	 * @param msgId
	 *            -发送出去的消息ID
	 * @return
	 */
	public static MassStatus queryStatus(String appId, String msgId) {
		JSONObject json = new JSONObject();
		json.put("msg_id", msgId);
		String msg = json.toString();
		String token = BaseAPI.getAccessToken(appId);
		if (token == null) {
			logger.error("查询群发消息发送状态失败，获取AccessToken失败!");
			return new MassStatus(-4, "获取AccessToken失败");
		}
		String url = MASS_MESSAGE_QUERY_STATUS.replace("ACCESS_TOKEN", token);
		logger.debug(json);
		return WxHttpUtils.post(url, msg, MassStatus.class);
	}
}
